#include "gd32f4_timer.h"
#include "gd32f4_timer_config.h"

static void GPIO_Config() {
#if TIMER_GENERAL_SW // 通用定时器引脚配置
    // 初始化复用功能输出
    GPIO_Output_Af_Cfg(TIMER_GPIO_RCU, TIMER_GPIO_PORT, TIMER_GPIO_PIN, TIMER_GPIO_AF, GPIO_OTYPE_PP, GPIO_PUPD_NONE);
#elif TIMER_ADVANCED_SW // 高级定时器引脚配置
    GPIO_Output_Af_Cfg(TIMER_N_RCU, TIMER_N_PORT, TIMER_N_PIN, TIMER_N_AF, GPIO_OTYPE_PP, GPIO_PUPD_NONE);
    GPIO_Output_Af_Cfg(TIMER_P_RCU, TIMER_P_PORT, TIMER_P_PIN, TIMER_P_AF, GPIO_OTYPE_PP, GPIO_PUPD_NONE);
#endif
}

/**
 * @brief 定时器基础配置
 * @param timer_rcu  // 定时器的时钟源
 * @param timer_periph  // 定时器外设
 * @param timer_period  // 定时器周期
 * @param timer_perscaler  // 定时器分频系数
 */
static void Timer_Basic_Config(rcu_periph_enum timer_rcu, uint32_t timer_periph,
                               uint32_t timer_period, uint16_t timer_perscaler) {
    // 开启外设时钟
    rcu_periph_clock_enable(timer_rcu);
    // 重置时钟
    timer_deinit(timer_periph);

    // 通过结构体配置参数
    timer_parameter_struct TIMER_InitStructure;
    timer_struct_para_init(&TIMER_InitStructure);
    // 修改关键值
    TIMER_InitStructure.period = timer_period - 1;       //---------->因为要配PWM现在这个真实周期了
    TIMER_InitStructure.prescaler = timer_perscaler - 1; // 因为是从0开始的

    // 定时器初始化
    timer_init(timer_periph, &TIMER_InitStructure);

    // 启用定时器
    timer_enable(timer_periph);
}

/**
 * @brief 定时器中断配置
 * @param timer_periph
 * @param timer_interrupt
 */
static void Timer_Interrupt_Config() {
    // 设置中断源，并配置中断优先级
    nvic_irq_enable(TIMER_IRQn, TIMER_PRE_PRIORITY, TIMER_SUB_PRIORITY);
    // 定时器中断使能,                这个UP不是向上计数。是update  有更新就能进来
    timer_interrupt_enable(TIMER_PERIPH, TIMER_INT_FLAG);
}

/**
 * @brief 定时器通道配置
 * @param timer_periph
 * @param timer_channel
 * @param flag 0无 1正极 2负极 3正负极
 */
static void Timer_Channel_Config(uint32_t timer_periph, uint16_t timer_channel, uint8_t flag) {
    // 创建通道结构体变量，并设置参数
    timer_oc_parameter_struct TIMER_OC_InitStructure;
    timer_channel_output_struct_para_init(&TIMER_OC_InitStructure);
    // 修改正负极配置
    if (flag == 1) {
        TIMER_OC_InitStructure.outputstate = TIMER_CCX_ENABLE; // 允许输出正极信号
    } else if (flag == 2) {
        TIMER_OC_InitStructure.outputnstate = TIMER_CCXN_ENABLE; // 允许输出负极信号
    } else if (flag == 3) {
        TIMER_OC_InitStructure.outputstate = TIMER_CCX_ENABLE;   // 允许输出正极信号
        TIMER_OC_InitStructure.outputnstate = TIMER_CCXN_ENABLE; // 允许输出负极信号
    }
    // 输出通道配置
    timer_channel_output_config(timer_periph, timer_channel, &TIMER_OC_InitStructure);
    // 输出通道模式配置
    timer_channel_output_mode_config(timer_periph, timer_channel, TIMER_PWM_MODE); // 模式0指高、模式1指低
}

// 其实时通道相关的，但是单独领出来好用
void MyTimer_PWM_Duty_Update(float duty) {
    //占空比设置
    timer_channel_output_pulse_value_config(TIMER_PERIPH, TIMER_CHANNEL, (duty / 100.0) * (TIMER_PERIOD - 1));
}

//更新周期和分频系数(内部调用2个蜂鸣器专用函数)
void MyTimer_Period_Prescaler_Update( uint32_t timer_period, uint16_t timer_perscaler) {
    // 更新定时器周期
    timer_autoreload_value_config(TIMER_PERIPH, timer_period - 1); // 因为是从0开始的，所以要-1
    // 更新定时器分频系数
    timer_prescaler_config(TIMER_PERIPH, timer_perscaler - 1,timer_period); // 因为是从0开始的，所以要-1
}

void MyTimer_Launch(){
     timer_enable(TIMER_PERIPH); // 启用定时器
}
void MyTimer_Stop(){
     timer_disable(TIMER_PERIPH); // 禁用定时器
}

/// @brief 解锁定时器电路保护
static void Timer_Break_UnLock(uint32_t timer_periph) {
    // break 只针对高级定时器TIMER0 & TIMER7，需要打开互补保护电路
    /* TIMER通道互补保护电路 */
    timer_break_parameter_struct breakpara;
    /* 初始化TIMER break参数结构体 */
    timer_break_struct_para_init(&breakpara);
    /* break输入的极性 HIGH */
    breakpara.breakpolarity = TIMER_BREAK_POLARITY_HIGH;
    /* 输出自动的启用 */
    breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;
    /* bread输入的启用*/
    breakpara.breakstate = TIMER_BREAK_ENABLE;
    /* 死区时间 [0, 255] */
    breakpara.deadtime = 0;
    /* 配置TIMER break */
    timer_break_config(timer_periph, &breakpara);
    /* 启用TIMER break */
    timer_break_enable(timer_periph);
}

void MyTimer_Init() {
    // 引脚初始化
    GPIO_Config();
    // 4倍频，最大到168M
    rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
    // 定时器基础配置
    Timer_Basic_Config(TIMER_RCU, TIMER_PERIPH, TIMER_PERIOD, TIMER_PRESCALER);

#if TIMER_BASIC_SW // 基本定时器---->中断配置
    Timer_Interrupt_Config();
#elif TIMER_GENERAL_SW || TIMER_ADVANCED_SW // 通用或高级定时器---->通道配置
    // 定时器通道配置
    Timer_Channel_Config(TIMER_PERIPH, TIMER_CHANNEL, TIMER_POLARITY);
    // 占空比配置
    MyTimer_PWM_Duty_Update(50.0);
#endif

#if TIMER_ADVANCED_SW // 高级定时器
    // 解锁定时器电路保护
    Timer_Break_UnLock(TIMER_PERIPH);
#endif
}

void TIMER_Handler() { //1ms调用一次中断
	if(SET == timer_interrupt_flag_get(TIMER_PERIPH, TIMER_INT_IN_FLAG)){
		// 清除中断标志位
		timer_interrupt_flag_clear(TIMER_PERIPH, TIMER_INT_IN_FLAG);
		//---------中断处理逻辑-----------
#if (TIMER_INT_RECALL_SW == 1)
		MyTimer_handler();
#endif
	}
}
